package com.bill99.golden.inf.sso.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.bill99.golden.inf.sso.dao.TokenDao;
import com.bill99.golden.inf.sso.mdp.model.SsoTokenInfo;
import com.bill99.golden.inf.sso.model.AppConfigInfoItem;
import com.bill99.golden.inf.sso.util.TokenLogUtil;
import com.bill99.golden.info.sso.model.Token;

public class TokenDBService implements ITokenLog {
	private static Log log = LogFactory.getLog(TokenDBService.class);
	private TokenDao tokenDao;
	private static Map<String, TempItem> visitTokenMap = new HashMap<String, TempItem>();
	private static Object lock = new Object();
	private Integer reserveTokenDays = 30;

	public void init() {
		TokenLogUtil.setTokenLog(this);
	}

	public void setTokenDao(TokenDao tokenDao) {
		this.tokenDao = tokenDao;
	}

	private Token toTokenModel(String token, SsoTokenInfo s) {
		if (s == null)
			return null;
		Token t = new Token();
		t.setToken(token);
		t.setAppCode(s.getAppCode());
		Map<String, AppConfigInfoItem> m = AppInfoData.getAppConfigMap();
		AppConfigInfoItem app = m.get(s.getAppCode());
		if (app != null)
			t.setAppName(app.getAppName());
		t.setCreateTime(s.getCreateTime());
		t.setUserIp(s.getUserIp());
		t.setExplorerType(s.getExplorerType());
		t.setUserId(s.getUserId());
		t.setUserCode(s.getUserCode());
		t.setUserName(s.getUserName());
		t.setOrgId(s.getOrgId());
		t.setOrgCode(s.getOrgCode());
		t.setOrgName(s.getOrgName());
		t.setDepartmentId(s.getDepartmentId());
		t.setDepartmentCode(s.getDepartmentCode());
		t.setDepartmentName(s.getDepartmentName());
		t.setMemo(s.getMemo());
		t.setLastAccessTime(new Date(s.getUpdateTime()));
		return t;
	}

	private SsoTokenInfo toSsoTokenInfo(Token s) {
		if (s == null)
			return null;
		SsoTokenInfo t = new SsoTokenInfo();
		t.setAppCode(s.getAppCode());
		t.setCreateTime(s.getCreateTime());
		t.setUserIp(s.getUserIp());
		t.setExplorerType(s.getExplorerType());
		t.setUserId(s.getUserId());
		t.setUserCode(s.getUserCode());
		t.setUserName(s.getUserName());
		t.setOrgId(s.getOrgId());
		t.setOrgCode(s.getOrgCode());
		t.setOrgName(s.getOrgName());
		t.setDepartmentId(s.getDepartmentId());
		t.setDepartmentCode(s.getDepartmentCode());
		t.setDepartmentName(s.getDepartmentName());
		t.setMemo(s.getMemo());
		t.setUpdateTime(s.getLastAccessTime().getTime());
		t.setVisitCount(s.getValidateCount());
		return t;
	}

	public void onCreateToken(String token, SsoTokenInfo ssoInfo) {
		// TODO Auto-generated method stub
		Token t = this.toTokenModel(token, ssoInfo);
		this.tokenDao.saveToken(t);
	}

	public void onDestroyToken(String token, SsoTokenInfo ssoInfo) {
		// TODO Auto-generated method stub
		this.tokenDao.destryToken(token);
	}

	public void onRefreshToken(String token, SsoTokenInfo ssoInfo) {
		// TODO Auto-generated method stub
		if (ssoInfo == null)
			return;
		synchronized (lock) {
			TempItem t = new TempItem();
			t.token = token;
			t.updateTime = ssoInfo.getUpdateTime();
			t.visitCnt = ssoInfo.getVisitCount();
			visitTokenMap.put(token, t);
		}
	}

	public void onValidateToken(String token, SsoTokenInfo ssoInfo,
			String validateResult) {
		// TODO Auto-generated method stub
		if (ssoInfo == null)
			return;
		synchronized (lock) {
			TempItem t = new TempItem();
			t.token = token;
			t.updateTime = ssoInfo.getUpdateTime();
			t.visitCnt = ssoInfo.getVisitCount();
			visitTokenMap.put(token, t);
		}
	}

	public void updateTokenData() {
		log.info("updateTokenData stating...............");
		List<TempItem> list = new ArrayList<TempItem>();
		try {
			synchronized (lock) {
				Iterator<TempItem> it = visitTokenMap.values().iterator();
				while (it.hasNext()) {
					TempItem tempItem = (TempItem) it.next();
					list.add(tempItem);
				}
				visitTokenMap.clear();
			}
			for (int i = 0; i < list.size(); i++) {
				TempItem t = list.get(i);
				this.tokenDao.validateToken(t.token, t.visitCnt, new Date(
						t.updateTime));
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		log.info("updateTokenData end::::updateTokenCnt=" + list.size());
	}

	public void deleteInvalidToken() {
		this.tokenDao.deleteInvalidToken(this.reserveTokenDays);
	}

	public void loadTokenFromDB() {
		log.info("loadTokenFromDB starting..............");
		List list = this.tokenDao.getTokenListFromDB();
		for (int i = 0; i < list.size(); i++) {
			Token t = (Token) list.get(i);
			SsoTokenInfo s = this.toSsoTokenInfo(t);
			TokenService.addTokenToBuffer(t.getToken(), s);
		}
		log.info("loadTokenFromDB end!!!!!!!!");
	}

	public void setReserveTokenDays(Integer reserveTokenDays) {
		this.reserveTokenDays = reserveTokenDays;
	}

}

class TempItem {
	String token;
	long updateTime;
	long visitCnt;
}
